#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
GUI线程模块
包含UI相关的线程类
"""

import os
import sys
from pathlib import Path
from PyQt5.QtCore import QThread, pyqtSignal

# 导入项目模块
sys.path.append(str(Path(__file__).resolve().parent.parent))
from core.model_manager import ModelManager

# 检查NLTK可用性
try:
    import nltk
    NLTK_AVAILABLE = True
except ImportError:
    NLTK_AVAILABLE = False

class ModelDownloadThread(QThread):
    """下载模型的后台线程"""
    
    progress = pyqtSignal(str)  # 进度信号
    finished = pyqtSignal(bool)  # 完成信号，带成功状态
    
    def __init__(self, ui_callback=None, download_type='model'):
        """
        初始化线程
        
        Args:
            ui_callback: UI回调函数
            download_type: 下载类型，'model'或'nltk'
        """
        super().__init__()
        self.ui_callback = ui_callback
        self.download_type = download_type
    
    def run(self):
        """线程主函数"""
        if self.download_type == 'nltk':
            self.check_nltk_data()
        else:
            self.check_models()
    
    def check_models(self):
        """检查模型文件"""
        self.progress.emit("正在检查模型...")
        
        try:
            # 使用core.model_manager中的ModelManager
            model_manager = ModelManager(ui_callback=self.ui_callback)
            
            # 检查模型文件
            if model_manager.check_model_files():
                self.progress.emit("所有模型文件已存在，无需下载")
                self.finished.emit(True)
            else:
                # 尝试下载模型
                self.progress.emit("检测到缺少模型文件，开始下载...")
                result = model_manager.download_dependencies()
                
                if result:
                    self.progress.emit("模型下载完成！")
                    self.finished.emit(True)
                else:
                    self.progress.emit("模型下载不完整，部分功能可能不可用")
                    self.finished.emit(False)
        except Exception as e:
            self.progress.emit(f"模型检查出错: {str(e)}")
            self.finished.emit(False)
    
    def check_nltk_data(self):
        """检查NLTK数据"""
        self.progress.emit("正在检查NLTK数据...")
        
        try:
            from config.paths import NLTK_DATA_DIR
            
            if not NLTK_AVAILABLE:
                self.progress.emit("NLTK未安装，请安装nltk和g2p_en模块")
                self.finished.emit(False)
                return
            
            # 配置NLTK使用项目内目录
            os.environ['NLTK_DATA'] = str(NLTK_DATA_DIR)
            nltk.data.path = [str(NLTK_DATA_DIR)]
            
            # 检查点文件可能位于不同位置，列出所有可能的路径
            punkt_possible_files = [
                NLTK_DATA_DIR / "tokenizers" / "punkt" / "english.pickle",
                NLTK_DATA_DIR / "tokenizers" / "punkt" / "PY3" / "english.pickle"
            ]
            
            # 直接检查必要文件是否存在
            required_data_packages = ['punkt', 'averaged_perceptron_tagger']
            
            # 检查必要文件
            missing_packages = []
            for package in required_data_packages:
                if package == 'punkt':
                    # 特殊处理punkt数据包
                    if any(file.exists() for file in punkt_possible_files):
                        self.progress.emit(f"NLTK数据 {package} 已存在")
                    else:
                        self.progress.emit(f"缺少NLTK数据: {package}")
                        missing_packages.append(package)
                else:
                    # 使用nltk内置方法检查其他数据包
                    try:
                        nltk.data.find(f'taggers/{package}')
                        self.progress.emit(f"NLTK数据 {package} 已存在")
                    except LookupError:
                        self.progress.emit(f"缺少NLTK数据: {package}")
                        missing_packages.append(package)
            
            # 如果有缺失文件，尝试下载
            if missing_packages:
                self.progress.emit(f"尝试下载缺失的NLTK数据: {', '.join(missing_packages)}")
                for package in missing_packages:
                    try:
                        self.progress.emit(f"下载 {package}...")
                        nltk.download(package, download_dir=str(NLTK_DATA_DIR))
                        self.progress.emit(f"成功下载 {package}")
                    except Exception as e:
                        self.progress.emit(f"下载 {package} 失败: {str(e)}")
            
            # 重新检查必要文件
            all_required_available = True
            for package in required_data_packages:
                try:
                    if package == 'punkt':
                        if not any(file.exists() for file in punkt_possible_files):
                            all_required_available = False
                            self.progress.emit(f"下载后仍缺少NLTK数据: {package}")
                    else:
                        nltk.data.find(f'taggers/{package}')
                except LookupError:
                    all_required_available = False
                    self.progress.emit(f"下载后仍缺少NLTK数据: {package}")
            
            # 准备g2p_en额外资源
            if all_required_available:
                self.progress.emit("准备g2p_en所需的额外资源...")
                model_manager = ModelManager(ui_callback=self.ui_callback)
                if model_manager.prepare_g2p_resources():
                    self.progress.emit("g2p_en额外资源准备完成")
                else:
                    self.progress.emit("准备g2p_en资源时出现问题，但不影响基本功能")
                
                self.progress.emit("所有NLTK数据已准备就绪")
                self.finished.emit(True)
            else:
                self.progress.emit("NLTK数据检查完成，但有缺失，请通过下载管理器下载")
                self.finished.emit(False)
                
        except Exception as e:
            self.progress.emit(f"检查NLTK数据时出错: {str(e)}")
            self.finished.emit(False)

class TTSThread(QThread):
    """语音合成后台线程"""
    
    progress = pyqtSignal(str)  # 进度信号
    finished = pyqtSignal(tuple)  # 完成信号，带有(成功状态, 音频路径)
    
    def __init__(self, engine, text, speaker_name, speed, parent=None):
        """
        初始化TTS线程
        
        Args:
            engine: TTS引擎实例
            text: 要合成的文本
            speaker_name: 角色名称
            speed: 语速因子
        """
        super().__init__(parent)
        self.engine = engine
        self.text = text
        self.speaker_name = speaker_name
        self.speed = speed
    
    def run(self):
        """线程主函数"""
        self.progress.emit(f"正在使用'{self.speaker_name}'合成语音...")
        
        try:
            audio_data, file_path = self.engine.synthesize(
                self.text, 
                self.speaker_name, 
                speed=self.speed, 
                play=False
            )
            
            if file_path:
                self.progress.emit(f"合成完成: {file_path}")
                self.finished.emit((True, file_path))
            else:
                self.progress.emit("合成失败")
                self.finished.emit((False, None))
        except Exception as e:
            self.progress.emit(f"合成错误: {str(e)}")
            self.finished.emit((False, None)) 